﻿namespace NetFx.SMIL
{
  using System;
  using System.Text;
  using System.Collections;
  using System.Collections.Generic;
  using System.Reflection;
  using System.Reflection.Emit;
  using NetFx.AGIL;
  using NetFx.SMIL.References;


  public enum StackSlotType : byte
  {
    Nothing   = 0,
    Value     = 1,  //?
    Integer   = 2,
    Long      = 3,
    Float     = 4,
    Double    = 5,
    Reference = 6, 
    Variable  = 7,
  }


  [Flags]
  public enum SmilOperandType :int
  {
    None            = 0x00000000,
    String          = 0x00000001,
    Const           = 0x00000002,
    PrimitiveType   = 0x00000003,
    Type            = 0x00000004,
    Field           = 0x00000005,
    Property        = 0x00000006,
    Constructor     = 0x00000007,
    Method          = 0x00000008,
    Signature       = 0x00000009,
    BinaryOperation = 0x0000000A,
    BranchCondition = 0x0000000B,
    Label           = 0x0000000C,
    LabelArray      = 0x0000000D,
    Array           = 0x0000000E,
    Member          = 0x0000000F,

  }

  public class SmilOperation
  {
    #region Opcodes 54
    public static readonly SmilOperation Idle;
    public static readonly SmilOperation Breakpoint;
    public static readonly SmilOperation Load;
    public static readonly SmilOperation LoadAddress;
    public static readonly SmilOperation LoadArguments;
    public static readonly SmilOperation Store;
    public static readonly SmilOperation Duplicate;
    public static readonly SmilOperation Discard;
    public static readonly SmilOperation Call;
    public static readonly SmilOperation CallIndirect;
    public static readonly SmilOperation CallVirtual;
    public static readonly SmilOperation TailCall;
    public static readonly SmilOperation Dap;
    public static readonly SmilOperation Return;
    public static readonly SmilOperation Branch;
    public static readonly SmilOperation Swtich;
    public static readonly SmilOperation LoadIndirect;
    public static readonly SmilOperation StoreIndirect;
    public static readonly SmilOperation UnaryOperate;
    public static readonly SmilOperation BinaryOperate;
    public static readonly SmilOperation LoadValueType;
    public static readonly SmilOperation StoreValueType;
    public static readonly SmilOperation CopyValueType;
    public static readonly SmilOperation MeasureValueType;
    public static readonly SmilOperation InitiateValueType;
    public static readonly SmilOperation Instantiate;
    public static readonly SmilOperation IsInstance;
    public static readonly SmilOperation Cast;
    public static readonly SmilOperation CreateArray;
    public static readonly SmilOperation CountElement;
    public static readonly SmilOperation Wrap;
    public static readonly SmilOperation Unwrap;
    public static readonly SmilOperation Convert;
    public static readonly SmilOperation Pick;
    public static readonly SmilOperation Plug;
    public static readonly SmilOperation PickAddress;
    public static readonly SmilOperation Throw;
    public static readonly SmilOperation Rethrow;
    public static readonly SmilOperation EndFilter;
    public static readonly SmilOperation EndFinally;
    public static readonly SmilOperation Leave;
    public static readonly SmilOperation Compare;
    public static readonly SmilOperation LoadMethod;
    public static readonly SmilOperation LoadVirtualMethod;
    public static readonly SmilOperation CheckFinite;
    public static readonly SmilOperation AllocateBytes;
    public static readonly SmilOperation VolatileAddress;
    public static readonly SmilOperation UnalignedAddress;
    public static readonly SmilOperation CopyBytes;
    public static readonly SmilOperation InitiateBytes;
    public static readonly SmilOperation LoadRefType;
    public static readonly SmilOperation LoadRefTypeToken;
    public static readonly SmilOperation LoadRefTypeAddress;
    public static readonly SmilOperation Prefix;
    #endregion
    #region Opcodes definitons
    public static SmilOperation[] AllSmilOpcodes = new SmilOperation[]
    {
      #region Idle
      /// 如果修补操作码，则填充空间。尽管可能消耗处理周期，但未执行任何有意义的操作。
      Idle                = SmilOperation.of("Idle",
                              AgilOperation.Nop,      null    //0: Hint for Nop
                            ),
      #endregion
      #region Breakpoint
      /// 向公共语言结构 (CLI) 发出信号以通知调试器已撞上了一个断点。
      Breakpoint          = SmilOperation.of("Breakpoint",
                              AgilOperation.Break,    null    //0:  Hint for Break
                            ),
      #endregion
      #region Load
      /// 将值加载到计算栈上。
      Load                = SmilOperation.of("Load",
                              AgilOperation.Ldc_I4_M1,
                              AgilOperation.Ldc_I4_0,
                              AgilOperation.Ldc_I4_1,
                              AgilOperation.Ldc_I4_2,
                              AgilOperation.Ldc_I4_3,
                              AgilOperation.Ldc_I4_4,
                              AgilOperation.Ldc_I4_5,
                              AgilOperation.Ldc_I4_6,
                              AgilOperation.Ldc_I4_7,
                              AgilOperation.Ldc_I4_8, null,   //0:  Hint for encoded consts.
                              AgilOperation.Ldc_I4_S,
                              AgilOperation.Ldc_I4,
                              AgilOperation.Ldc_I8,   null,   //1:  Hint for int consts
                              AgilOperation.Ldc_R4,
                              AgilOperation.Ldc_R8,   null,   //2:  Hint for real consts.
                              AgilOperation.Ldarg_0,
                              AgilOperation.Ldarg_1,
                              AgilOperation.Ldarg_2,
                              AgilOperation.Ldarg_3,  null,   //3:  Hint for encoded arguments.
                              AgilOperation.Ldarg_S,
                              AgilOperation.Ldarg,    null,   //4:  Hint for other arguments.
                              AgilOperation.Ldloc_0,
                              AgilOperation.Ldloc_1,
                              AgilOperation.Ldloc_2,
                              AgilOperation.Ldloc_3,  null,   //5:  Hint for encoded locals
                              AgilOperation.Ldloc_S,
                              AgilOperation.Ldloc,    null,   //6:  Hint for other locals
                              AgilOperation.Ldsfld,   null,   //7:  Hint for static field
                              AgilOperation.Ldfld,    null,   //8:  Hint for instance field
                              AgilOperation.Ldnull,   null,   //9:  Hint for null literal
                              AgilOperation.Ldstr,    null,   //10: Hint for string literal
                              AgilOperation.Ldtoken,  null    //11: Hint for token
                            ),
      #endregion
      #region LoadAddress
      /// 将地址加载到计算栈上。
      LoadAddress         = SmilOperation.of("LoadAddress",
                              AgilOperation.Ldarga,
                              AgilOperation.Ldarga_S, null,   //0:  Hint for argument addresses
                              AgilOperation.Ldloca,
                              AgilOperation.Ldloca_S, null,   //1:  Hint for local addresses
                              AgilOperation.Ldsflda,  null,   //2:  Hint for static field addresses
                              AgilOperation.Ldflda,   null    //3:  Hint for instance field address
                            ),
      #endregion
      #region LoadArguments
      /// 返回指向当前方法的参数列表的非托管指针。
      LoadArguments       = SmilOperation.of("LoadArguments",
                              AgilOperation.Arglist,  null    //0:  Hint for argument list
                            ),
      #endregion
      #region Store
      /// 将值从计算栈存储到指定的位置。
      Store               = SmilOperation.of("Store",
                              AgilOperation.Stloc_0,
                              AgilOperation.Stloc_1,
                              AgilOperation.Stloc_2,
                              AgilOperation.Stloc_3,  null,   //0:  Hint for encoded locals
                              AgilOperation.Stloc_S,
                              AgilOperation.Stloc,    null,   //1:  Hint for other locals
                              AgilOperation.Starg,
                              AgilOperation.Starg_S,  null,   //2:  Hint for arguments
                              AgilOperation.Stsfld,   null,   //3:  Hint for static fields
                              AgilOperation.Stfld,    null    //4:  Hint for instance fields
                            ),
      #endregion
      #region Duplicate
      /// 复制计算堆栈上当前最顶端的值，然后将副本推送到计算堆栈上
      Duplicate           = SmilOperation.of("Duplicate",
                              AgilOperation.Dup,      null    //0:  Hint for dup
                            ),
      #endregion
      #region Discard
      /// 移除当前位于计算堆栈顶部的值。
      Discard             = SmilOperation.of("Discard",
                              AgilOperation.Pop,      null    //0:  Hint for pop
                            ),
      #endregion
      #region Call
      /// 调用由传递的方法说明符指示的方法。
      Call                = SmilOperation.of("Call",
                              AgilOperation.Call,     null    //0:  Hint for call
                            ),
      #endregion
      #region CallIndirect
      /// 通过调用约定描述的参数调用在计算堆栈上指示的方法（作为指向入口点的指针）。
      CallIndirect        = SmilOperation.of("CallIndirect",
                              AgilOperation.Calli,    null    //0:  Hint for calli
                            ),
      #endregion
      #region CallVirtual
      /// 对对象调用后期绑定方法，并且将返回值推送到计算堆栈上。
      CallVirtual         = SmilOperation.of("CallVirtual",
                              AgilOperation.Callvirt, null    //0:  Hint for callvirt
                            ),
      #endregion
      #region TailCall
      /// 执行后缀的方法调用指令，以便在执行实际调用指令前移除当前方法的堆栈帧。
      TailCall            = SmilOperation.of("TailCall",
                              AgilOperation.Tailcall, null    //0:  Hint for tailcall
                            ),
      #endregion 
      #region Dap
      /// 退出当前方法并跳至指定方法。
      Dap                 = SmilOperation.of("Dap",
                              AgilOperation.Jmp,      null    //0:  Hint for jump
                            ),
      #endregion
      #region Return
      /// 从当前方法返回，并将返回值（如果存在）从调用方的计算堆栈推送到被调用方的计算堆栈上。
      Return              = SmilOperation.of("Return",
                              AgilOperation.Ret,      null    //0:  Hint for ret
                            ),
      #endregion
      #region Branch
      /// 当条件成立的时候转移
      Branch              = SmilOperation.of("Branch",
                              AgilOperation.Beq,
                              AgilOperation.Beq_S,
                              AgilOperation.Bge,
                              AgilOperation.Bge_S,
                              AgilOperation.Bgt,
                              AgilOperation.Bgt_S,
                              AgilOperation.Ble,
                              AgilOperation.Ble_S,
                              AgilOperation.Blt,
                              AgilOperation.Blt_S,    null,   //0:  Hint for signed cond branching
                              AgilOperation.Bne_Un,
                              AgilOperation.Bne_Un_S,
                              AgilOperation.Bge_Un,
                              AgilOperation.Bge_Un_S,
                              AgilOperation.Bgt_Un,
                              AgilOperation.Bgt_Un_S,
                              AgilOperation.Ble_Un,
                              AgilOperation.Ble_Un_S,
                              AgilOperation.Blt_Un,   
                              AgilOperation.Blt_Un_S, null,   //1:  Hint for unsigned cond branching
                              AgilOperation.Brfalse,
                              AgilOperation.Brfalse_S,null,   //2:  Hint for false branching
                              AgilOperation.Brtrue,
                              AgilOperation.Brtrue_S, null,   //3:  Hint for true branching
                              AgilOperation.Br,
                              AgilOperation.Br_S,     null    //4:  Hint for uncond branching
                            ),
      #endregion
      #region Switch
      /// 返回指向当前方法的参数列表的非托管指针。
      Swtich              = SmilOperation.of("Swtich",
                              AgilOperation.Switch,   null    //0:  Hint for switch
                            ),
      #endregion
      #region LoadIndirect
      /// 将值间接加载到计算栈上。
      LoadIndirect        = SmilOperation.of("LoadIndirect",
                              AgilOperation.Ldind_Ref,null,   //0:  Hint for ref loading
                              AgilOperation.Ldind_I,  null,   //1:  Hint for ldind_native_int
                              AgilOperation.Ldind_I1,
                              AgilOperation.Ldind_I2,
                              AgilOperation.Ldind_I4,
                              AgilOperation.Ldind_I8, null,   //2:  Hint for ldind_int
                              AgilOperation.Ldind_U1,
                              AgilOperation.Ldind_U2,
                              AgilOperation.Ldind_U4, null,   //3:  Hint for ldind_uint
                              AgilOperation.Ldind_R4, 
                              AgilOperation.Ldind_R8, null    //4:  Hint for ldind_real
                            ),
      #endregion
      #region StoreIndirect
      /// 在所提供的地址存储指定类型的值
      StoreIndirect       = SmilOperation.of("StoreIndirect",
                              AgilOperation.Stind_Ref,null,   //0:  Hint for ref stroing
                              AgilOperation.Stind_I,  null,   //1:  Hint for stind_native_int
                              AgilOperation.Stind_I1,
                              AgilOperation.Stind_I2,
                              AgilOperation.Stind_I4,
                              AgilOperation.Stind_I8, null,   //2:  Hint for stind_int
                              AgilOperation.Stind_I1,
                              AgilOperation.Stind_I2,
                              AgilOperation.Stind_I4,
                              AgilOperation.Stind_I8, null,   //3:  Hint for stind_uint (int simulated)
                              AgilOperation.Stind_R4,
                              AgilOperation.Stind_R8, null    //4:  Hint for stind_real
                            ),
      #endregion
      #region UnaryOperate
      /// 对给定值进行一元运算。
      UnaryOperate        = SmilOperation.of("UnaryOperate",
                              AgilOperation.Neg,      null,   //0:  Hint for neg
                              AgilOperation.Not,      null    //1:  Hint for not
                            ),
      #endregion
      #region BinaryOperate
      /// 对两个给定值进行二元运算。
      BinaryOperate       = SmilOperation.of("BinaryOperate",
                              AgilOperation.Add,
                              AgilOperation.Add_Ovf,
                              AgilOperation.Add_Ovf_Un, null, //0:  Hint for add
                              AgilOperation.Sub,
                              AgilOperation.Sub_Ovf,
                              AgilOperation.Sub_Ovf_Un, null, //1:  Hint for sub
                              AgilOperation.Mul,
                              AgilOperation.Mul_Ovf,
                              AgilOperation.Mul_Ovf_Un, null, //2:  Hint for mul
                              AgilOperation.Div,
                              AgilOperation.Div_Un,     null, //3:  Hint for div
                              AgilOperation.Rem,
                              AgilOperation.Rem_Un,     null, //4:  Hint for rem
                              AgilOperation.And,        null, //5:  Hint for and
                              AgilOperation.Or,         null, //6:  Hint for or
                              AgilOperation.Xor,        null, //7:  Hint for xor
                              AgilOperation.Shl,        null, //8:  Hint for shl
                              AgilOperation.Shr,
                              AgilOperation.Shr_Un,     null  //9:  Hint for shr
                            ),
      #endregion
      #region LoadValueType
      /// 将地址指向的值类型对象复制到计算堆栈的顶部。
      LoadValueType       = SmilOperation.of("LoadValueType",
                              AgilOperation.Ldobj,      null  //0:  Hint for ldobj
                            ),
      #endregion
      #region StoreValueType
      /// 将指定类型的值从计算堆栈复制到所提供的内存地址中
      StoreValueType      = SmilOperation.of("StoreValueType",
                              AgilOperation.Stobj,      null  //0:  Hint for stobj
                            ),
      #endregion
      #region CopyValueType
      /// 将位于对象（&、* 或 natural int 类型）地址的值类型复制到目标对象（&、* 或 natural int 类型）的地址。
      CopyValueType       = SmilOperation.of("CopyValueType",
                              AgilOperation.Cpobj,      null  //0:  Hint for cpobj
                            ),
      #endregion
      #region MeasureValueType
      /// 将提供的值类型的大小（以字节为单位）推送到计算堆栈上。
      MeasureValueType    = SmilOperation.of("MeasureValueType",
                              AgilOperation.Sizeof,     null  //0:  Hint for sizeof
                            ),
      #endregion
      #region InitiateValueType
      /// 将位于指定地址的对象的所有字段初始化为空引用或适当的基元类型的 0。
      InitiateValueType   = SmilOperation.of("InitiateValueType",
                              AgilOperation.Initobj,    null  //0:  Hint for initobj
                            ),
      #endregion
      #region Instantiate
      /// 创建一个值类型的新对象或新实例，并将对象引用（O 类型）推送到计算堆栈上。
      Instantiate         = SmilOperation.of("Instantiate",
                              AgilOperation.Newobj,     null  //0:  Hint for newobj
                            ),
      #endregion
      #region IsInstance
      /// 测试对象引用（O 类型）是否为特定类的实例。
      IsInstance          = SmilOperation.of("IsInstance",
                              AgilOperation.Isinst,     null  //0:  Hint for isinst
                            ),
      #endregion
      #region Cast
      /// 尝试将引用传递的对象转换为指定的类。
      Cast                = SmilOperation.of("Cast",
                              AgilOperation.Castclass,  null  //0:  Hint for castclass
                            ),
      #endregion
      #region CreateArray
      /// 将对新的从零开始的一维数组（其元素属于特定类型）的对象引用推送到计算堆栈上。
      CreateArray         = SmilOperation.of("CreateArray",
                              AgilOperation.Newarr,     null  //0:  Hint for newarr
                            ),
      #endregion
      #region CountElement
      /// 将从零开始的、一维数组的元素的数目推送到计算堆栈上。
      CountElement        = SmilOperation.of("CountElement",
                              AgilOperation.Ldlen,      null  //0:  Hint for ldlen
                            ),
      #endregion 
      #region Wrap
      /// 将值类转换为对象引用（O 类型）。
      Wrap                = SmilOperation.of("Wrap",
                              AgilOperation.Box,        null  //0:  Hint for box
                            ),
      #endregion
      #region Unwrap
      /// 将值类型的已装箱的表示形式转换为其未装箱的形式。
      Unwrap              = SmilOperation.of("Unwrap",
                              AgilOperation.Unbox,      null, //0:  Hint for unbox
                              AgilOperation.Unbox_Any,  null  //0:  Hint for unbox_any
                            ),
      #endregion
      #region Convert
      /// 转换位于计算堆栈顶部的值到指定类型。
      Convert             = SmilOperation.of("Convert",
                              AgilOperation.Conv_I,
                              AgilOperation.Conv_Ovf_I,
                              AgilOperation.Conv_Ovf_I_Un,null, //0:  Hint for native int
                              AgilOperation.Conv_U,
                              AgilOperation.Conv_Ovf_U,
                              AgilOperation.Conv_Ovf_U_Un,null, //1:  Hint for native uint
                              AgilOperation.Conv_I1,
                              AgilOperation.Conv_Ovf_I1,
                              AgilOperation.Conv_Ovf_I1_Un,null,//2:  Hint for I1
                              AgilOperation.Conv_I2,
                              AgilOperation.Conv_Ovf_I2,
                              AgilOperation.Conv_Ovf_I2_Un,null,//3:  Hint for I2
                              AgilOperation.Conv_I4,
                              AgilOperation.Conv_Ovf_I4,
                              AgilOperation.Conv_Ovf_I4_Un,null,//4:  Hint for I4
                              AgilOperation.Conv_I8,
                              AgilOperation.Conv_Ovf_I8,
                              AgilOperation.Conv_Ovf_I8_Un,null,//5:  Hint for I8
                              AgilOperation.Conv_U1,
                              AgilOperation.Conv_Ovf_U1,
                              AgilOperation.Conv_Ovf_U1_Un,null,//6:  Hint for U1
                              AgilOperation.Conv_U2,
                              AgilOperation.Conv_Ovf_U2,
                              AgilOperation.Conv_Ovf_U2_Un,null,//7:  Hint for U2
                              AgilOperation.Conv_U4,
                              AgilOperation.Conv_Ovf_U4,
                              AgilOperation.Conv_Ovf_U4_Un,null,//8:  Hint for U4
                              AgilOperation.Conv_U8,
                              AgilOperation.Conv_Ovf_U8,
                              AgilOperation.Conv_Ovf_U8_Un,null,//9:  Hint for U8
                              AgilOperation.Conv_R_Un,     null,//10: Hint for native real
                              AgilOperation.Conv_R4,       null,//11: Hint for real4
                              AgilOperation.Conv_R8,       null //12: Hint for real8

                            ),
      #endregion
      #region Pick
      /// 从数组的指定下标上取出元素。
      Pick                = SmilOperation.of("Pick",
                              AgilOperation.Ldelem_Any,   null, //0:Hint for ldelem_any
                              AgilOperation.Ldelem_Ref,   null, //1:Hint for ldelem_ref
                              AgilOperation.Ldelem_I,     null, //2:Hint for ldelem_native_int
                              AgilOperation.Ldelem_I1,
                              AgilOperation.Ldelem_I2,
                              AgilOperation.Ldelem_I4,
                              AgilOperation.Ldelem_I8,    null, //3:Hint for ldelem_int
                              AgilOperation.Ldelem_U1,
                              AgilOperation.Ldelem_U2,
                              AgilOperation.Ldelem_U4,    
                              AgilOperation.Ldelem_I8,    null, //4:Hint for ldelem_uint (I8 simulated U8)
                              AgilOperation.Ldelem_R4,
                              AgilOperation.Ldelem_R8,    null  //5:Hint for ldelem_real
                            ),
      #endregion
      #region Plug
      /// 向数组的指定位置上存储元素。
      Plug                = SmilOperation.of("Plug",
                              AgilOperation.Stelem_Any,   null, //0:Hint for stelem_any
                              AgilOperation.Stelem_Ref,   null, //1:Hint for stelem_ref
                              AgilOperation.Stelem_I,     null, //2:Hint for stelem_native_int
                              AgilOperation.Stelem_I1,
                              AgilOperation.Stelem_I2,
                              AgilOperation.Stelem_I4,
                              AgilOperation.Stelem_I8,    null, //3:Hint for stelem_int
                              AgilOperation.Stelem_I1,
                              AgilOperation.Stelem_I2,
                              AgilOperation.Stelem_I4,
                              AgilOperation.Stelem_I8,    null, //4:Hint for stelem_uint (int simulated)
                              AgilOperation.Stelem_R4,
                              AgilOperation.Stelem_R8,    null  //5:Hint for stelem_real
                            ),
      #endregion
      #region PickAddress
      /// 从数组的指定下标上取出元素的地址。
      PickAddress         = SmilOperation.of("PickAddress",
                              AgilOperation.Ldelema,      null  //0:Hint for ldelema
                            ),
      #endregion
      #region Throw
      /// 掷出异常
      Throw               = SmilOperation.of("Throw",
                              AgilOperation.Throw,        null  //0:Hint for throw
                            ),
      #endregion
      #region Rethrow
      /// 重新掷出异常
      Rethrow             = SmilOperation.of("Rethrow",
                              AgilOperation.Rethrow,      null  //0:Hint for rethrow
                            ),
      #endregion
      #region EndFilter
      /// 将控制从异常的 filter 子句转移回公共语言结构 (CLI) 异常处理程序。
      EndFilter           = SmilOperation.of("EndFilter",
                              AgilOperation.Endfilter,    null  //0:Hint for endfilter
                            ),
      #endregion
      #region EndFinally
      /// 将控制从异常块的 fault 或 finally 子句转移回公共语言结构 (CLI) 异常处理程序。
      EndFinally          = SmilOperation.of("EndFinally",
                              AgilOperation.Endfinally,   null  //0:Hint for endfinally
                            ),
      #endregion
      #region Leave
      /// 退出受保护的代码区域，无条件将控制转移到特定目标指令。
      Leave               = SmilOperation.of("Leave",
                              AgilOperation.Leave,
                              AgilOperation.Leave_S,      null  //0:Hint for leave
                            ),
      #endregion
      #region Compare
      /// 比较两个值。符合条件，则将整数值 1 ((int32) 推送到计算堆栈上；否则，将 0 (int32) 推送到计算堆栈上。
      Compare             = SmilOperation.of("Compare",
                              AgilOperation.Ceq,          null, //0:Hint for ceq
                              AgilOperation.Cgt,
                              AgilOperation.Cgt_Un,       null, //1:Hint for cgt
                              AgilOperation.Clt,
                              AgilOperation.Clt_Un,       null  //2:Hint for clt
                            ),
      #endregion
      #region LoadMethod
      /// 将指向实现特定方法的本机代码的非托管指针（natural int 类型）推送到计算堆栈上。
      LoadMethod          = SmilOperation.of("LoadMethod",
                              AgilOperation.Ldftn,        null  //0:Hint for ldftn
                            ),
      #endregion
      #region LoadVirtualMethod
      /// 将指向实现与指定对象关联的特定虚方法的本机代码的非托管指针（natural int 类型）推送到计算堆栈上。
      LoadVirtualMethod   = SmilOperation.of("LoadVirtualMethod",
                              AgilOperation.Ldvirtftn,    null  //0:Hint for ldvirtftn
                            ),
      #endregion
      #region CheckFinite
      /// 如果值不是有限数，则引发 ArithmeticException。
      CheckFinite         = SmilOperation.of("CheckFinite",
                              AgilOperation.Ckfinite,     null  //0:Hint for ckfinite
                            ),
      #endregion
      #region AllocateBytes
      /// 从本地动态内存池分配特定数目的字节并将第一个分配的字节的地址（瞬态指针，* 类型）推送到计算堆栈上。
      AllocateBytes       = SmilOperation.of("AllocateBytes",
                              AgilOperation.Localloc,     null  //0:Hint for localloc
                            ),
      #endregion
      #region VolatileAddress
      /// 指定该地址是易失地址
      VolatileAddress     = SmilOperation.of("VolatileAddress",
                              AgilOperation.Volatile,     null  //0:Hint for volatile
                            ),
      #endregion
      #region UnalignedAddress
      /// 指示当前位于计算堆栈上的地址可能没有与紧接的 ldind、stind、ldfld、stfld、ldobj、stobj、initblk 或 cpblk 指令的自然大小对齐。
      UnalignedAddress    = SmilOperation.of("UnalignedAddress",
                              AgilOperation.Unaligned,    null  //0:Hint for unaligned
                            ),
      #endregion
      #region CopyBytes
      /// 将指定数目的字节从源地址复制到目标地址。
      CopyBytes           = SmilOperation.of("CopyBytes",
                              AgilOperation.Cpblk,        null  //0:Hint for cpblk
                            ),
      #endregion
      #region InitiateBytes
      /// 将位于特定地址的内存的指定块初始化为给定大小和初始值。
      InitiateBytes       = SmilOperation.of("InitiateBytes",
                              AgilOperation.Initblk,      null  //0:Hint for initblk
                            ),
      #endregion
      #region LoadRefType
      /// 将对特定类型实例的类型化引用推送到计算堆栈上。
      LoadRefType         = SmilOperation.of("LoadRefType",
                              AgilOperation.Mkrefany,     null  //0:Hint for mkrefany
                            ),
      #endregion
      #region LoadRefTypeToken
      /// 检索嵌入在类型化引用内的类型标记。
      LoadRefTypeToken    = SmilOperation.of("LoadRefTypeToken",
                              AgilOperation.Refanytype,   null  //0:Hint for refanytype
                            ),
      #endregion
      #region LoadRefTypeAddress
      /// 检索嵌入在类型化引用内的地址（& 类型）。
      LoadRefTypeAddress  = SmilOperation.of("LoadRefTypeAddress",
                              AgilOperation.Refanyval,    null  //0:Hint for refanyval
                            ),
      #endregion
      #region Prefix
      /// 保留的前缀
      Prefix              = SmilOperation.of("Prefix",
                              AgilOperation.Prefixref,    null, //0:Hint for prefixref
                              AgilOperation.Prefix1,
                              AgilOperation.Prefix2,
                              AgilOperation.Prefix3,
                              AgilOperation.Prefix4,
                              AgilOperation.Prefix5,
                              AgilOperation.Prefix6,
                              AgilOperation.Prefix7,      null  //1:Hint for prefixes
                            ),
      #endregion
    };

    #endregion
    #region Statics
    #region Fields
    protected static int codeCount = 0;
    #endregion
    #region Properties
    public static int CodeCount
    {
      get
      {
        return codeCount;
      }
    }
    #endregion
    #region Operators
    #endregion
    #region Methods
    public static SmilOperation GetAccordingOpcodeOf(AgilOperation agil)
    {
      foreach (SmilOperation sop in AllSmilOpcodes)
      {
        if (sop != null && sop.Equals(agil))
        {
          return sop.Clone(agil);
        }
      }
      return null;
    }
    #endregion
    #region Shortcuts
    protected static SmilOperation of(SmilOperation source,int index)
    {
      return new SmilOperation(source,index);
    }
    protected static SmilOperation of(SmilOperation source,int index,SmilOperand operand)
    {
      return new SmilOperation(source,index,operand);
    }
    protected static SmilOperation of(string name, params AgilOperation[] relativeAgils)
    {
      return of(name, codeCount++, relativeAgils);
    }
    protected static SmilOperation of(string name, int code, params AgilOperation[] relativeAgils)
    {
      return new SmilOperation(name, code, relativeAgils);
    }
    #endregion
    #endregion
    #region Fields
    protected int code = 0;
    protected int index = -1;
    protected string name = string.Empty;
    protected AgilOperation[] relativeAgils = null;
    protected SmilOperand operand = null;
    #endregion
    #region Properties
    public virtual string Name
    {
      get
      {
        return this.Name;
      }
    }
    public virtual int Code
    {
      get
      {
        return this.code;
      }
    }
    public virtual bool HasOperand
    {
      get
      {
        return this.operand != null;
      }
    }
    public virtual SmilOperand Operand
    {
      get
      {
        return this.operand;
      }
    }
    public virtual bool HasUnderlyingAgil
    {
      get
      {
        return this.index >= 0 && this.index < this.relativeAgils.Length;
      }
    }
    public virtual AgilOperation UnderlyingAgil
    {
      get
      {
        return this.HasUnderlyingAgil ?
          this.RelativeAgils[this.index] :
          null;
      }
    }
    public virtual AgilOperation[] RelativeAgils
    {
      get
      {
        return this.relativeAgils;
      }
    }
    /// <summary>
    /// 获取堆栈压入类型序列。
    /// </summary>
    public virtual Type[] PushStack
    {
      get
      {
        return this.HasUnderlyingAgil ?
          this.UnderlyingAgil.PushStack:
          null;
      }
    }
    /// <summary>
    /// 获取堆栈弹出类型序列。
    /// </summary>
    public virtual Type[] PopStack
    {
      get
      {
        return this.HasUnderlyingAgil ?
          this.UnderlyingAgil.PopStack:
          null;
      }
    }
    #endregion
    #region Constructors
    protected SmilOperation(string name, int code,params AgilOperation[] relativeAgils)
    {
      this.name = name;
      this.code = code;
      this.relativeAgils = relativeAgils == null ? new AgilOperation[0] : relativeAgils;
    }

    protected SmilOperation(SmilOperation source,int index):this(source,index,null)
    {
    }
    protected SmilOperation(SmilOperation source,int index,SmilOperand operand)
    {
      if (source != null)
      {
        this.index = index;
        this.name = source.name;
        this.code = source.code;
        this.relativeAgils = source.relativeAgils;
        this.operand = operand;
      }
    }
    #endregion
    #region Methods
    #region Compare
    public virtual bool Equals(SmilOperation opcode)
    {
      return opcode != null ? this.code == opcode.Code : false;
    }
    public virtual bool Equals(AgilOperation agil)
    {
      return agil != null ? (this.GetAgilIndexOf(agil) >= 0) : false;
    }
    public virtual int GetAgilIndexOf(AgilOperation agil)
    {
      if (agil != null && this.RelativeAgils!=null)
      {
        for (int index = 0; index < this.RelativeAgils.Length; index++)
        {
          AgilOperation currentAgil = this.RelativeAgils[index];
          if (currentAgil != null && currentAgil.IsOpcodeMatched(agil))
          {
            return index;
          }
        }
      }
      return -1;
    }
    #endregion
    #region Clone
    public virtual SmilOperation Clone(AgilOperation agil)
    {
      SmilOperation clone = null;
      if (this.Equals(agil))
      {
        clone = of(this, this.GetAgilIndexOf(agil),  SmilOperand.of(this.GetReference(agil)));
      }
      return clone;
    }
    public virtual SmilOperation SetOperand(SmilOperand operand)
    {
      this.operand = operand;

      return this;
    }
    protected virtual Reference GetReference(AgilOperation agil)
    {
      Reference reference = null;
      if (agil!= null)
      {
        switch (agil.MsilOperandCat)
        {
          case MsilOperandCat.Const:
            reference = ConstRef.of(agil.Operand);
            break;
          case MsilOperandCat.Argument:
            reference = VariableRef.of(agil.VariableName);
            break;
          case MsilOperandCat.Local:
            reference = VariableRef.of(agil.VariableName);
            break;
          case MsilOperandCat.Class:
            reference = TypeRef.of(agil.TypeOperand);
            break;
          case MsilOperandCat.Field:
            reference = FieldRef.of(agil.FieldOperand);
            break;
          case MsilOperandCat.Method:
            reference = MethodRef.of(agil.MethodOperand);
            break;
          case MsilOperandCat.Null:
            reference = NullRef.it();
            break;
          case MsilOperandCat.Offset:
            reference = LabelRef.of(agil.Labels);
            break;
          case MsilOperandCat.OffsetList:
            reference = LabelsRef.of(agil.LabelList);
            break;
          case MsilOperandCat.String:
            reference = StringRef.of(agil.StringOperand);
            break;
          case MsilOperandCat.Token:
            reference = MemberRef.of(agil.MemberOperand);
            break;
          case MsilOperandCat.Signature:
            reference = SignatureRef.of(agil.SignatureOperand);
            break;
        }
      }
      return reference;
    }
    #endregion
    #region Format
    public virtual void LogFormatAt(OperationFormatResolver resolver)
    {
      if (resolver != null)
      {
        this.OnLogFormatAt(resolver);
      }
    }
    public virtual void SetFormatAt(OperationFormatResolver resolver, bool? isLongFormat)
    {
      if (resolver != null)
      {
        this.OnSetFormatAt(resolver, isLongFormat);
      }
    }
    protected virtual void OnLogFormatAt(OperationFormatResolver resolver)
    {

    }
    protected virtual void OnSetFormatAt(OperationFormatResolver resolver, bool? isLongFormat)
    {

    }
    #endregion
    #region Overrides
    public override string ToString()
    {
      return string.Empty;
    }
    public override int GetHashCode()
    {
      return this.code;
    }
    public override bool Equals(object obj)
    {
      if (obj is SmilOperation)
      {
        return this.code == (obj as SmilOperation).code;
      }
      else if (obj is AgilOperation)
      {
        return this.Equals(obj as AgilOperation);
      }
      return false;
    }
    #endregion
    #endregion
  }
}
